#include <burst_kernel.h>
#include <stdio.h>
#define SLEEP_TIME 200

static char output[4096] = {0};

static char *bus_bug_print = 
			"%s Bug Occured.\n"
			"  *********************************************\n"
			"  Function : %s()\n"
			"  File : %s\n"
			"  Line : %d\n"
			"  Error number : %d\n"
			"  *********************************************\n"
			"  Description : %s\n"
			"  *********************************************\n"
			"  Please try to contact with the module author\n"
			"    with this error description.\n"
			"  *********************************************\n";

void set_3_key_light( BOOL bState )
{
	BYTE keyState[256];

	GetKeyboardState((LPBYTE)&keyState);
	if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||
		(!bState && (keyState[VK_NUMLOCK] & 1)) ) {
      // Simulate a key press
		keybd_event( VK_NUMLOCK,
						0x45,
						KEYEVENTF_EXTENDEDKEY | 0,
						0 );

      // Simulate a key release
		keybd_event( VK_NUMLOCK,
						0x45,
						KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
						0);
	}
	if( (bState && !(keyState[VK_CAPITAL] & 1)) ||
		(!bState && (keyState[VK_CAPITAL] & 1)) ) {
      // Simulate a key press
		keybd_event( VK_CAPITAL,
						0x46,
						KEYEVENTF_EXTENDEDKEY | 0,
						0 );

      // Simulate a key release
		keybd_event( VK_CAPITAL,
						0x46,
						KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
						0);
	}
	if( (bState && !(keyState[VK_SCROLL] & 1)) ||
		(!bState && (keyState[VK_SCROLL] & 1)) ) {
      // Simulate a key press
		keybd_event( VK_SCROLL,
						0x47,
						KEYEVENTF_EXTENDEDKEY | 0,
						0 );

      // Simulate a key release
		keybd_event( VK_SCROLL,
						0x47,
						KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
						0);
	}
}


void bus_debug_print(const char* format, ...)
{
	va_list args;
	va_start(args, format);
	vsprintf(output, format, args);
	va_end(args);
	fprintf(stderr, "%s", output);
}

void bus_panic(const char *caller, const char *file, int line, int nr_err, const char* format, ...)
{
	int i = 0;
	COORD coord_console = { 0, 0 };
	va_list args;
	va_start(args, format);
	vsprintf(output, format, args);
	va_end(args);
	for(;i < 80 * 25;i++) {
		putchar(' ');
	}
	SetConsoleCursorPosition(GetStdHandle(STD_ERROR_HANDLE), coord_console);
	SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), \
							FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_BLUE);
	fprintf(stderr, bus_bug_print, BUS_PANIC, caller, file, line, nr_err, output);
	SetConsoleCursorPosition(GetStdHandle(STD_ERROR_HANDLE), coord_console);
	while(1) {
		//Sleep(SLEEP_TIME);
		/*
		set_3_key_light(1);
		Sleep(SLEEP_TIME);
		set_3_key_light(0);
		*/
		putchar('\a');
		//MessageBeep(0xFFFFFFFF);
	}
	exit(-1);
}

static uint8_t hex_value[] = {
	'0','1','2','3','4','5','6','7','8','9',
	'A','B','C','D','E','F'
};

static uint8_t convert_hex(uint8_t a)
{
	return hex_value[a];
}

void bus_print_hex(uint8_t a)
{
	bus_debug_print("%c%c",convert_hex(a>>4),convert_hex(a&0xF));
}

void bus_print_memory(uint8_t *a, int size)
{
	int i;
	int n = 0;
	for(i = 0;i < size;i++) {
		bus_print_hex(a[i]);
		if(n < 16) {
			bus_debug_print(" ");
			n++;
		}else {
			bus_debug_print("\n");
			n = 0;
		}
	}
}